package org.zjx.swing.font;

import com.sun.jna.platform.win32.WinDef.RECT;
import org.zjx.swing.bean.ParagraphBean;
import org.zjx.swing.bean.ParagraphBean.Word;
import org.zjx.swing.bean.WordBean;
import org.zjx.swing.bean.Font;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class FontUtil {

    /**
     * 打印点阵信息
     * @param wordBeanss
     */
    public static void printBlock(List<List<WordBean>> wordBeanss) {
        for (List<WordBean> wordBeans : wordBeanss) {
            for (WordBean wordBean : wordBeans) {
                LiterateUtil.printBlock(wordBean.getBlock());
                System.out.println(wordBean.getRect().toString());
            }
            System.out.println("============================================================");
        }
    }


    public static BufferedImage getBufferedImage(WordBean wordBean) {
        // 获取矩形的宽度和高度
        int width = wordBean.getWith();
        int height = wordBean.getHeight();
        // 创建一个 BufferedImage 对象，指定图像的宽度和高度
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 遍历 block 数组，填充颜色
        for (int i = 0; i < wordBean.getBlock().length; i++) {
            for (int j = 0; j < wordBean.getBlock()[i].length; j++) {
                // 获取 block 数组中的值，0 为白色，1 为黑色
                int colorValue = wordBean.getBlock()[i][j] == 1 ? Color.BLACK.getRGB() : Color.WHITE.getRGB();

                // 设置像素点
                image.setRGB(j, i, colorValue);
            }
        }
        return image;
    }


    private static void matching(List<List<WordBean>> wordList, List<Font> fonts) throws Exception {
        if (wordList == null || fonts == null) return;
        for (List<WordBean> wordBeans : wordList) {
            matchingList(wordBeans, fonts);
        }
    }

    private static void matchingList(List<WordBean> wordBeans, List<Font> fonts) throws Exception {
        int i = 0; // 初始化索引
        while (i < wordBeans.size()) {
            WordBean currentWordBean = wordBeans.get(i);
            if (currentWordBean == null) {
                i++;
                continue;
            }
            // 如果当前 wordBean 匹配失败，开始尝试合并后再匹配
            if (matching(currentWordBean, fonts) == null) {
                boolean isMerged = false;

                // 尝试合并多个 wordBean
                for (int j = 1; j <= 3; j++) {
                    if (i + j < wordBeans.size()) {
                        // 合并当前 wordBean 和接下来的 j 个 wordBean
                        WordBean mergedWordBean = currentWordBean;
                        for (int k = 1; k <= j; k++) {
                            mergedWordBean = LiterateUtil.mergeWord(mergedWordBean, wordBeans.get(i + k));
                        }

                        // 如果合并后的 wordBean 可以匹配字库，则更新并清理已合并的部分
                        if (matching(mergedWordBean, fonts) != null) {
                            wordBeans.set(i, mergedWordBean); // 设置合并后的 WordBean

                            // 清理已合并的元素
                            for (int k = i + 1; k <= i + j; k++) {
                                wordBeans.set(k, null);
                            }

                            isMerged = true;
                            break; // 合并成功后跳出循环
                        }
                    }
                }

                // 如果合并后的 wordBean 仍然无法匹配字库，则抛出异常
                if (!isMerged) {
//                    throw new Exception("字库不全，无法匹配 WordBean: " + currentWordBean);

                }
            }

            // 如果当前索引的元素是 null，表示已经处理过，跳过
            if (wordBeans.get(i) == null) {
                i++; // 跳过已处理的 null 元素
            } else {
                i++; // 继续处理下一个元素
            }
        }

        // 移除为 null 的元素，清理无用数据
        wordBeans.removeIf(Objects::isNull);
    }


    public static String matching(WordBean wordBean, List<Font> fonts) {
        for (org.zjx.swing.bean.Font font : fonts) {
            if (wordBean.getWith() == font.getWide() && wordBean.getHeight() == font.getHigh() && arrayToString(wordBean.getBlock()).equals(font.getBlock())) {
                wordBean.setName(font.getName());
                return wordBean.getName();
            }
        }
        return null;
    }


    /**
     * 分割合并段落词组
     * @param name
     * @param colors
     * @param image
     * @return
     */
    public static ParagraphBean.Categories categories(String name, List<Color> colors, BufferedImage image, List<Font> fonts, int wordHeight) throws Exception {
        List<List<WordBean>> wordBeanss = LiterateUtil.identify(image, wordHeight, colors);
//        printBlock(wordBeanss);
        matching(wordBeanss, fonts);
        ParagraphBean.Categories categories = new ParagraphBean.Categories();
        categories.setCategory(name);
        FontUtil.structured(wordBeanss, categories);
        return categories;
    }

    /**
     * 一行不同段落规整
     * @param wordBeanss
     */
    private static void structured(List<List<WordBean>> wordBeanss, ParagraphBean.Categories categories) {
        if (wordBeanss == null || categories == null) return;

        for (List<WordBean> wordBeans : wordBeanss) {
            if (categories.getWords() == null) categories.setWords(new ArrayList<>());
            if (wordBeans.isEmpty()) continue;
            List<WordBean> currentParagraph = new ArrayList<>();
            currentParagraph.add(wordBeans.get(0));

            for (int i = 1; i < wordBeans.size(); i++) {
                WordBean currentBean = wordBeans.get(i);
                WordBean lastBean = currentParagraph.get(currentParagraph.size() - 1);

                // 判断两个 WordBean 是否连续
                if (currentBean.getLeft() - lastBean.getRight() <= 10) {
                    currentParagraph.add(currentBean); // 合并
                } else {
                    addParagraph(currentParagraph, categories);
                    currentParagraph.clear();
                    currentParagraph.add(currentBean); // 新段落
                }
            }

            // 处理最后一个段落
            if (!currentParagraph.isEmpty()) {
                addParagraph(currentParagraph, categories);
            }
        }
    }

    // 辅助方法：合并段落并添加到 categories 中
    private static void addParagraph(List<WordBean> currentParagraph, ParagraphBean.Categories categories) {
        RECT rect = new RECT();
        rect.left = currentParagraph.get(0).getRect().left;
        rect.right = currentParagraph.get(currentParagraph.size() - 1).getRect().right;
        rect.top = currentParagraph.get(0).getRect().top;
        rect.bottom = currentParagraph.get(currentParagraph.size() - 1).getRect().bottom;

        StringBuilder paragraphName = new StringBuilder();
        for (WordBean bean : currentParagraph) {
            paragraphName.append(bean.getName());
        }

        categories.getWords().add(new Word(paragraphName.toString().trim(), rect));
    }

    // 将二维数组（0和1）转换成字符串
    public static String arrayToString(int[][] array) {
        StringBuilder sb = new StringBuilder();
        for (int[] row : array) {
            for (int j : row) {
                sb.append(j);
            }
        }
        return sb.toString().trim(); // 去掉末尾的换行符
    }

    // 将字符串转换成二维数组（传入字符串和宽高）
    public static int[][] stringToArray(String str, int width, int height) {
        int[][] array = new int[height][width];
        String[] rows = str.split("\n"); // 以换行符分割字符串为行
        for (int i = 0; i < height; i++) {
            String[] cols = rows[i].split(","); // 以逗号分割每行的元素
            for (int j = 0; j < width; j++) {
                array[i][j] = Integer.parseInt(cols[j].trim()); // 转换为整数
            }
        }
        return array;
    }
}
